// 反射
// go 语言不支持解析string 然后执行，反射机制只能作用于已经存在的对象上
// package main

// import (
// 	"fmt"
// 	"reflect"
// )

// func main() {
// 	var a interface{} = "我是字符串"
// 	typeOfa := reflect.TypeOf(a)
// 	fmt.Println("变量a的类型为:", typeOfa)
// 	valueOfa := reflect.ValueOf(a)
// 	if typeOfa.Kind() == reflect.String {
// 		fmt.Println("变量a的值为:", valueOfa)

// 	}
// }

// 获取类型信息
// package main

// import (
// 	"fmt"
// 	"reflect"
// )

// type Number int

// type Person struct {
// }

// func checkType(t reflect.Type) {
// 	if t.Kind() == reflect.Ptr {
// 		fmt.Printf("变量的类型名称为%v, 指向的变量为%v:", t.Kind(), t.Elem())
// 		t = t.Elem()
// 	}
// 	fmt.Printf("变量的类型名称为=>%v, 类型种类为=>%v\n", t.Name(), t.Kind())
// }

// func main() {
// 	var num Number = 10
// 	typeOfNum := reflect.TypeOf(num)
// 	fmt.Println("typeOfNum")
// 	checkType(typeOfNum)

// 	var person Person
// 	typeOfPerson := reflect.TypeOf(person)
// 	fmt.Println("typeOfPerson")
// 	checkType(typeOfPerson)

// 	typeOfPersonPtr := reflect.TypeOf(&person)
// 	fmt.Println("typeOfPersonPtr")
// 	checkType(typeOfPersonPtr)
// }

// 获取类型的值
// package main

// import (
// 	"fmt"
// 	"reflect"
// )

// func checkValue(v reflect.Value) {
// 	if v.Kind() == reflect.Ptr {
// 		v = v.Elem()
// 	}
// 	if v.Kind() == reflect.Int {
// 		var v1 int = int(v.Int())
// 		var v2 int = v.Interface().(int)
// 		fmt.Println(v1, v2)
// 	}

// }

// func main() {
// 	var num int = 10
// 	valueOfNum := reflect.ValueOf(num)
// 	fmt.Println("valueOfNum")
// 	checkValue(valueOfNum)

// 	valueOfPtr := reflect.ValueOf(&num)
// 	fmt.Println("valueOfPtr")
// 	checkValue(valueOfPtr)
// }

// 使用反射调用函数

// package main

// import (
// 	"fmt"
// 	"reflect"
// )

// func Equal(a, b int) bool {
// 	if a == b {
// 		return true
// 	}
// 	return false
// }

// func main() {
// 	// 反射调用函数需要使用ValueOf
// 	valueOfFunc := reflect.ValueOf(Equal)

// 	// 构造函数参数
// 	args := []reflect.Value{reflect.ValueOf(1), reflect.ValueOf(2)}

// 	// 通过反射调用函数计算
// 	result := valueOfFunc.Call(args)

// 	fmt.Println("函数运行结果:", result[0].Bool())
// }

// 对结构体的反射操作
// package main

// import (
// 	"fmt"
// 	"reflect"
// )

// type Person struct {
// 	Name string
// 	Age  int `json:"age"`
// 	string
// }

// func (p Person) GetName() {
// 	fmt.Println(p.Name)
// }

// func main() {
// 	person := Person{"小张", 10, "备注"}
// 	// typeOfPerson := reflect.TypeOf(person)

// 	// // 遍历所有结构体成员获取字段信息
// 	// fmt.Println("遍历结构体")
// 	// for i := 0; i < typeOfPerson.NumField(); i++ {
// 	// 	field := typeOfPerson.Field(i)
// 	// 	fmt.Printf("字段名：%v 字段标签: %v 是否匿名字段：%v\n", field.Name, field.Tag, field.Anonymous)
// 	// }
// 	// // 通过字段名获取字段信息
// 	// if field, ok := typeOfPerson.FieldByName("Age"); ok {
// 	// 	fmt.Println("通过字段名")
// 	// 	fmt.Printf("字段名：%v, 字段标签中json：%v\n", field.Name, field.Tag.Get("json"))
// 	// }

// 	// // 通过下标获取字段信息
// 	// field := typeOfPerson.FieldByIndex([]int{1})
// 	// fmt.Println("通过下标")
// 	// fmt.Printf("字段名:%v, 字段标签: %v\n", field.Name, field.Tag)

// 	// 获取结构体成员字段的值
// 	// valueOfPerson := reflect.ValueOf(person)
// 	// fmt.Printf("person的字段数量为:%v\n", valueOfPerson.NumField())

// 	// // 通过下标访问获取字段值
// 	// fmt.Println("field")
// 	// field := valueOfPerson.Field(1)
// 	// fmt.Printf("字段值:%v\n", field.Int())
// 	// // 通过字段名获取字段值
// 	// field = valueOfPerson.FieldByName("Age")
// 	// fmt.Println("FieldName")
// 	// fmt.Printf("字段值:%v\n", field.Interface())
// 	// // 通过下标索引获取字段值
// 	// field = valueOfPerson.FieldByIndex([]int{0})
// 	// fmt.Println("FieldByIndex")
// 	// fmt.Printf("字段值:%v\n", field.Interface())

// 	// 反射执行结构体方法
// 	valueOfPerson := reflect.ValueOf(person)
// 	// 根据名字获取方法
// 	f := valueOfPerson.MethodByName("GetName")
// 	// 执行结构体方法
// 	f.Call([]reflect.Value{})

// }

// 反射定律
// 反射可以将接口类型变量转换为反射类型变量
// 反射可以将反射类型变量转换为接口变量
// 使用反射来修改变量的值， 其值必须是可写的（变量可被寻址， 变量是可导出的即结构体字段名首字母大写）

package main

import (
	"fmt"
	"reflect"
)

type Person struct {
	Name string
	Age  int `json:"age"`
	string
}

// func main() {
// 	var a int = 5
// 	fmt.Printf("type:%T\n", reflect.TypeOf(a))
// 	fmt.Printf("value: %T\n", reflect.ValueOf(a))

// 	valueOfA := reflect.ValueOf(a)
// 	fmt.Println(valueOfA.Interface())
// }

func main() {
	person := Person{"lian", 20, "爱好"}
	// valueOfPerson := reflect.ValueOf(person)
	// typeOfPerson := reflect.TypeOf(person)

	valueOfPerson := reflect.ValueOf(&person)
	typeOfPerson := reflect.TypeOf(&person)

	for i := 0; i < valueOfPerson.Elem().NumField(); i++ {
		fieldValue := valueOfPerson.Elem().Field(i)
		fieldType := typeOfPerson.Elem().Field(i)
		fmt.Printf("类型名：%v 可以寻址； %v 可以设置：%v\n", fieldType.Name,
			fieldValue.CanAddr(), fieldValue.CanSet())
	}
	fmt.Println("修改前：", person)
	valueOfPerson.Elem().Field(0).SetString("gang")
	valueOfPerson.Elem().Field(1).SetInt(27)
	// valueOfPerson.Elem().Field(2).SetString("something")
	fmt.Println("修改后:", person)

}
